package cn.tedu.xxmall.filter;

import cn.tedu.xxmall.security.LoginPrincipal;
import com.alibaba.fastjson.JSON;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * @author : Jimmy
 * @date : 2022-08-26 20:19
 **/
@Slf4j
@Component
public class JwtAuthorizationFilter extends OncePerRequestFilter {

    public static final String REQUEST_HEADER_AUTHORIZATION="Authorization";

    @Value("${xxmall.jwt.secretKey}")
    private String secretKey;

    public JwtAuthorizationFilter() {
        log.debug("创建JwtAuthorizationFilter过滤器");
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        SecurityContextHolder.clearContext();
        log.debug("执行JwtAuthorizationFilter");
        String jwt = request.getHeader(REQUEST_HEADER_AUTHORIZATION);
        log.debug("从请求头中获取JWT：{}", jwt);
        if (!StringUtils.hasText(jwt)||jwt.length()<80){
            log.debug("获取到的JWT是无效的，直接放行，交由后续的组件继续处理！");
            // 过滤器链继续执行，相当于：放行
            filterChain.doFilter(request, response);
            // 返回，终止当前方法本次执行
            return;
        }
        response.setContentType("application/json; charset=utf-8");
        Claims claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwt).getBody();
        Long id = claims.get("id",Long.class);
        String username = claims.get("username",String.class);
        String authorityListString = claims.get("authorities",String.class);
        log.debug("从JWT中解析得到id：{}", id);
        log.debug("从JWT中解析得到username：{}", username);
        log.debug("从JWT中解析得到authorities：{}", authorityListString);
        LoginPrincipal loginPrincipal = new LoginPrincipal();
        loginPrincipal.setId(id);
        loginPrincipal.setUsername(username);
        log.debug("从JWT中解析得到username：{}", username);
        List<SimpleGrantedAuthority> authorities = JSON.parseArray(authorityListString.toString(), SimpleGrantedAuthority.class);
        Authentication authentication = new UsernamePasswordAuthenticationToken(loginPrincipal,null,authorities);
        SecurityContext context = SecurityContextHolder.getContext();
        context.setAuthentication(authentication);
        log.debug("已经向Security的上下文中写入：{}", authentication);
        // 过滤器链继续执行，相当于：放行
        filterChain.doFilter(request, response);
    }
}
